From 1fd01489f9691a8465810633643c88fd243ebd18 Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Thu, 5 Jul 2007 14:46:13 +0100 Subject: [PATCH] [HVM] Shadow: avoid xen crash if guest uses special memory for pagetables (just crash the guest and don't do any more PTE propagations). Signed-off-by: Tim Deegan --- xen/arch/x86/mm/shadow/common.c | 11 +++++++---- xen/arch/x86/mm/shadow/multi.c | 13 ++++++++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index eb015b7a1b..7e53c23a36 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -506,7 +506,9 @@ void shadow_promote(struct vcpu *v, mfn_t gmfn, unsigned int type) ASSERT(mfn_valid(gmfn)); /* We should never try to promote a gmfn that has writeable mappings */ - ASSERT(sh_remove_write_access(v, gmfn, 0, 0) == 0); + ASSERT((page->u.inuse.type_info & PGT_type_mask) != PGT_writable_page + || (page->u.inuse.type_info & PGT_count_mask) == 0 + || v->domain->is_shutting_down); /* Is the page already shadowed? */ if ( !test_and_set_bit(_PGC_page_table, &page->count_info) ) @@ -1850,11 +1852,12 @@ int sh_remove_write_access(struct vcpu *v, mfn_t gmfn, perfc_incr(shadow_writeable_bf); hash_foreach(v, callback_mask, callbacks, gmfn); - /* If that didn't catch the mapping, something is very wrong */ + /* If that didn't catch the mapping, then there's some non-pagetable + * mapping -- ioreq page, grant mapping, &c. */ if ( (mfn_to_page(gmfn)->u.inuse.type_info & PGT_count_mask) != 0 ) { - SHADOW_ERROR("can't find all writeable mappings of mfn %lx: " - "%lu left\n", mfn_x(gmfn), + SHADOW_ERROR("can't remove write access to mfn %lx: guest has " + "%lu special-use mappings of it\n", mfn_x(gmfn), (mfn_to_page(gmfn)->u.inuse.type_info&PGT_count_mask)); domain_crash(v->domain); } diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 962caa05ee..6e2f7b92b2 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -2719,10 +2719,21 @@ static int sh_page_fault(struct vcpu *v, if ( guest_walk_tables(v, va, &gw, 1) != 0 ) { - SHADOW_PRINTK("malformed guest pagetable!"); + SHADOW_PRINTK("malformed guest pagetable\n"); print_gw(&gw); } + /* It's possible that the guest has put pagetables in memory that it has + * already used for some special purpose (ioreq pages, or granted pages). + * If that happens we'll have killed the guest already but it's still not + * safe to propagate entries out of the guest PT so get out now. */ + if ( unlikely(d->is_shutting_down) ) + { + SHADOW_PRINTK("guest is shutting down\n"); + shadow_unlock(d); + return 0; + } + sh_audit_gw(v, &gw); // We do not look at the gw->l1e, as that will not exist for superpages. -- 2.30.2